﻿using IntoCommon.Util;
using IntoStationSystem.Db;
using IntoStationSystem.Entity;
using IntoStationSystem.Global;
using IntoStationSystem.Models;
using IntoStationSystem.PLC;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using static IntoStationSystem.Global.Events;

namespace IntoStationSystem.ViewModels
{
    public class ProductSettingViewModel : BindableBase
    {
        private Service service => Locator.Instance.Service;

        private MainWindowViewModel wvm => Locator.Instance.MainWindowVM;
        /// <summary>
        /// 界面显示产品参数
        /// </summary>
        public ObservableCollection<ProductModel> Production { get; set; } = new ObservableCollection<ProductModel>();
        /// <summary>
        /// 界面显示扫码配置
        /// </summary>
        public ObservableCollection<ScanModel> ScanCodes { get; set; } = new ObservableCollection<ScanModel>();

        /// <summary>
        /// 保存产品型号索引
        /// </summary>
        public ObservableCollection<ModelIndex> ModelIndexs { get; set; } = new ObservableCollection<ModelIndex>();

        public ObservableCollection<string> Products { get; set; } = new ObservableCollection<string>();
        public List<ScanModel> EnableScans { get; set; } = new List<ScanModel>();
        public string CurModeName = string.Empty;
        #region property
        private string newProduct;
        /// <summary>
        /// 新增加的产品
        /// </summary>
        public string NewProduct
        {
            get => newProduct;
            set => SetProperty(ref newProduct, value);
        }
        private string _selectedProduct;
        /// <summary>
        /// 当前选择型号
        /// </summary>
        public string SelectedProduct
        {
            get { return _selectedProduct; }
            set
            {
                _selectedProduct = value;
                RaisePropertyChanged("SelectedProduct");
                Load(value);
            }
        }

        private int proIndex;
        /// <summary>
        /// 型号索引
        /// </summary>
        public int ProIndex
        {
            get => proIndex; set => SetProperty(ref proIndex, value);
        }

        #endregion

        public ProductSettingViewModel()
        {
            //DbHelper.Log($"ProductSettingViewModel");
            LoadConfig();
            EventRepository.EventAggregator.GetEvent<MesChangeRecipeEvent>().Subscribe(UpdateProductConfig);
        }
        /// <summary>
        /// 加载配置
        /// </summary>
        private void LoadConfig()
        {
            var names = DbHelper.GetProductNames();
            if (names != null)
            {
                foreach (var name in names)
                {
                    Products.Add(name);
                }
            }
            var config = DbHelper.GetConfig<ProductModel>();
            if (config != null && config.Count > 0)
            {
                foreach (var pro in config)
                {
                    Production.Add(pro);
                }
            }
            else
            {
                for (int i = 0; i < Fields.ProductParaCount; i++)
                {
                    Production.Add(new ProductModel()
                    {
                        Index = i + 1,
                        RealValue = 1.1f,
                        RealDesc = $"real{i + 1}",
                        ByteValue = 10,
                        ByteDesc = $"byte{i + 1}",
                    });
                }
                //DbHelper.SetDefault<ProductModel>();
            }

            var scanCfg = DbHelper.GetConfig<ScanCode>();
            if (scanCfg != null && scanCfg.Count > 0)
            {
                for (int i = 0; i < Fields.ScanCount; i++)
                {
                    ScanCodes.Add(new ScanModel()
                    {
                        Index = i + 1,
                        PartName = scanCfg[i].PartName,
                        Enable = scanCfg[i].Enable,
                        CodeLen = scanCfg[i].CharLen,
                        MatchCode = scanCfg[i].MatchChar
                    });
                }
            }
            else
            {
                for (int i = 0; i < Fields.ScanCount; i++)
                {
                    ScanCodes.Add(new ScanModel() { Index = i + 1, PartName = $"零件名称{i + 1}" });
                }
                DbHelper.SetDefault<ScanCode>();
            }

            var modelIndex = DbHelper.GetConfig<ModelIndex>();
            if (modelIndex != null && modelIndex.Count > 0)
            {
                for (int i = 0; i < modelIndex.Count; i++)
                {
                    ModelIndexs.Add(new ModelIndex()
                    {
                        
                        Index = modelIndex[i].Index,
                        Name = modelIndex[i].Name,

                    });
                }
            }
            else
            {
                ModelIndexs.Add(new ModelIndex() { Index =1, Name = "昆仑X" });
                ModelIndexs.Add(new ModelIndex() { Index = 2, Name = "MS11" });
                DbHelper.SetDefault<ModelIndex>();
            }

        }
        /// <summary>
        /// 发送对应型号名称的参数给PLC
        /// </summary>
        /// <param name="modelName"></param>
        private void SendProductModelPara(string modelName)
        {
            var mapReal = Fields.Map["SetReals"];
            var mapByte = Fields.Map["SetBytes"];
            int dbAddr = Fields.SetDbAddr;
            var config = DbHelper.GetConfig<ProductModel>(modelName);
            if (config == null || config.Count == 0) return;
            wvm.CollectionSteps = config[4].RealValue;
            float[] reals = new float[64];
            byte[] bytes = new byte[64];
            for (int i = 0; i < 64; i++)
            {
                reals[i] = config[i].RealValue;
                bytes[i] = config[i].ByteValue;
            }
            service.WriteData(mapReal.First, reals, dbAddr);
            service.WriteData(mapByte.First, bytes, dbAddr);
            DbHelper.LogTip("发送产品型号参数");
        }
        /// <summary>
        /// 更新扫码配置
        /// </summary>
        private void UpdateScanConfig(string modelName)
        {
            var config = DbHelper.GetConfig<ScanCode>(modelName);
            if (config != null && config.Count > 0)
            {
                EnableScans.Clear();
                foreach (var scan in config)
                {
                    if (scan.Enable)
                    {
                        EnableScans.Add(new ScanModel()
                        {
                            Enable = scan.Enable,
                            PartName = scan.PartName,
                            MatchCode = scan.MatchChar,
                            CodeLen = scan.CharLen,
                        });
                    }
                }
            }
            else
            {
                DbHelper.Log("记录该工位无扫码配置");
            }
        }
        /// <summary>
        /// 保存当前型号的配置参数
        /// </summary>
        private void Save()
        {
            if (string.IsNullOrEmpty(_selectedProduct))
            {
                //记录选择为空不能保存
                return;
            }
            for (int i = 0; i < Fields.ProductParaCount; i++)
            {
                Production[i].Name = _selectedProduct;
            }
            DbHelper.SaveConfig(Production.ToList(), _selectedProduct);
            List<ScanCode> scans = new List<ScanCode>();
            for (int i = 0; i < Fields.ScanCount; i++)
            {
                scans.Add(new ScanCode()
                {
                    Enable = ScanCodes[i].Enable,
                    ProductName = _selectedProduct,
                    PartName = ScanCodes[i].PartName,
                    MatchChar = ScanCodes[i].MatchCode,
                    CharLen = ScanCodes[i].CodeLen
                });
            }
            DbHelper.SaveConfig(scans, _selectedProduct);
            DbHelper.SaveConfig(ModelIndexs.ToList(), _selectedProduct);
            UpdateScanConfig(_selectedProduct);
        }
        /// <summary>
        /// 选择型号后加载新的数据
        /// </summary>
        private void Load(string proName)
        {
            var pros = DbHelper.GetConfig<ProductModel>(proName);
            var scans = DbHelper.GetConfig<ScanCode>(proName);
            var Input = DbHelper.GetConfig<IOStateModel>(proName);
            bool isHasPros = pros != null && pros.Count > 0;
            bool isHasScans = scans != null && scans.Count > 0;
            for (int i = 0; i < Fields.ProductParaCount; i++)
            {
                Production[i].Name = isHasPros ? pros[i].Name : proName;
                Production[i].RealDesc = isHasPros ? pros[i].RealDesc : $"real{i + 1}";
                Production[i].RealValue = isHasPros ? pros[i].RealValue : 1.1f;
                Production[i].ByteDesc = isHasPros ? pros[i].ByteDesc : $"byte{i + 1}";
                Production[i].ByteValue = isHasPros ? pros[i].ByteValue : (byte)1;
                Production[i].Index = isHasPros ? pros[i].Index : i + 1;
            }
            for (int i = 0; i < Fields.ScanCount; i++)
            {
                ScanCodes[i].IsScan = false;
                ScanCodes[i].CodeLen = isHasScans ? scans[i].CharLen : 10;
                ScanCodes[i].Index = i + 1;
                ScanCodes[i].MatchCode = isHasScans ? scans[i].MatchChar : $"请输入校验码{i + 1}";
                ScanCodes[i].Enable = isHasScans ? scans[i].Enable : false;
                ScanCodes[i].PartName = isHasScans ? scans[i].PartName : $"零件名称{1 + i}";
            }
        }

        /// <summary>
        /// 更新产品配置
        /// </summary>
        /// <param name="name"></param>
        public void UpdateProductConfig(string name)
        {
            SendProductModelPara(name);
            UpdateScanConfig(name);
        }
        /// <summary>
        /// 添加新的产品型号
        /// </summary>
        private void Add()
        {
            Production.Clear();
            ScanCodes.Clear();
           var arr=newProduct.Split(',');
            if (arr.Count() == 1 || arr.Count() == 0)
            {
                HandyControl.Controls.MessageBox.Show("输入有问题，型号与索引逗号隔开，例如（昆仑X,1），保持与mes下发的索引一致!");
                return;
            }
            for (int i = 0; i < Fields.ProductParaCount; i++)
            {
                Production.Add(new ProductModel()
                {
                    Index = i + 1,
                    Name = arr[0],
                    RealDesc = $"real{i + 1}",
                    RealValue = 1,
                    ByteDesc = $"byte{i + 1}",
                    ByteValue = 1,
                });
            }
            for (int i = 0; i < Fields.ScanCount; i++)
            {
                ScanCodes.Add(new ScanModel() { Index = i + 1, Enable = false, PartName = $"零件名称{i + 1}", MatchCode = $"请输入校验码{i + 1}", CodeLen = 10 });
            }
            if (!Products.Contains(newProduct))
            {
                Products.Add(arr[0]);
            }
            if (ModelIndexs.Where(p => p.Name == arr[0]).ToList().Count() <= 0)
            {
               
                ModelIndexs.Add(new ModelIndex() { Index = Convert.ToInt32(arr[1]), Name = arr[0] });
            }

            SelectedProduct = arr[0];
        }
        /// <summary>
        /// 删除产品型号
        /// </summary>
        private void Delete()
        {
            DbHelper.DeleteConfig<ProductModel>(_selectedProduct);
            DbHelper.DeleteConfig<ScanCode>(_selectedProduct);
            DbHelper.DeleteConfig<ModelIndex>(_selectedProduct);
            ModelIndexs.Remove(ModelIndexs.Where(p=>p.Name== _selectedProduct).FirstOrDefault());
            Products.Remove(_selectedProduct);
        }

        /// <summary>
        /// 锁
        /// </summary>
        private object locker = new object();

        /// <summary>
        /// 发送参数给PLC
        /// </summary>
        private void Send()
        {
            Task.Run(() =>
            {
                lock (locker)
                {
                    if (string.IsNullOrEmpty(_selectedProduct))
                    {
                        DbHelper.Log("未选择产品型号");
                        return;
                    }
                    //远程模式不允许发送

                    UpdateProductConfig(_selectedProduct);

                    //查找对应模型索引
                    var mi=ModelIndexs.Where(p => p.Name == _selectedProduct).FirstOrDefault();

                    //发送当前型号索引
                    byte[] data = new byte[1] { (byte)(mi.Index) };
                    Locator.Instance.Service.WriteData(Fields.Map["Model"].First, data);
                    //SendProductModelPara(_selectedProduct);
                }
            });
        }

        private DelegateCommand saveCmd;
        private DelegateCommand deleteCmd;
        private DelegateCommand addCmd;
        private DelegateCommand sendCmd;
        public DelegateCommand SaveCmd => saveCmd ?? (saveCmd = new DelegateCommand(Save));
        public DelegateCommand DeleteCmd => deleteCmd ?? (deleteCmd = new DelegateCommand(Delete));
        public DelegateCommand AddCmd => addCmd ?? (addCmd = new DelegateCommand(Add));
        public DelegateCommand SendCmd => sendCmd ?? (sendCmd = new DelegateCommand(Send));
    }
}
